﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.ComponentModel;
using System.Reflection;
using System.Security.Cryptography;

namespace WebeTerm.Common
{
    /// <summary>
    /// 字符串工具
    /// </summary>
    public static class StringUtil {
        private static string __lastKey = string.Empty;
        /// <summary>
        /// 产生一个新的36位主键唯一编号.
        /// </summary>
        /// <value>The new36 primary key.</value>
        public static string New36PrimaryKey {
            get {
                __lastKey = Guid.NewGuid().ToString().Replace("-", string.Empty);
                return __lastKey;
            }
        }



        /// <summary>
        /// 将字符串格式化成指定的数据类型
        /// </summary>
        /// <param name="str"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static Object Format(this String str, Type type)
        {
            if (String.IsNullOrEmpty(str))
                return null;
            if (type == null)
                return str;
            if (type.IsArray)
            {
                Type elementType = type.GetElementType();
                String[] strs = str.Split(new char[] { ';' });
                Array array = Array.CreateInstance(elementType, strs.Length);
                for (int i = 0, c = strs.Length; i < c; ++i)
                {
                    array.SetValue(ConvertSimpleType(strs[i], elementType), i);
                }
                return array;
            }
            return ConvertSimpleType(str,type);
        }

        private static object ConvertSimpleType(object value, Type destinationType)
        {
            object returnValue;
            if ((value == null) || destinationType.IsInstanceOfType(value))
            {
                return value;
            }
            string str = value as string;
            if ((str != null) && (str.Length == 0))
            {
                return null;
            }
            TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
            bool flag = converter.CanConvertFrom(value.GetType());
            if (!flag)
            {
                converter = TypeDescriptor.GetConverter(value.GetType());
            }
            if (!flag && !converter.CanConvertTo(destinationType))
            {
                throw new InvalidOperationException("无法转换成类型：" + value.ToString() + "==>" + destinationType);
            }
            try
            {
                returnValue = flag ? converter.ConvertFrom(null, null, value) : converter.ConvertTo(null, null, value, destinationType);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("类型转换出错：" + value.ToString() + "==>" + destinationType, e);
            }
            return returnValue;
        }
    


        public static string ToSymbol(this bool v, TemplateControl c)
        {
            string url = c.ResolveUrl(@"~/Styles/Images");
            return string.Format(@"<img src=""{0}/{1}"" border=""0"" />", url, v ? @"yes.png" : @"no.png");
        }

        public static string ToSymbol(this bool? v, TemplateControl c)
        {
            return (v ?? false).ToSymbol(c);
        }



        public static string ToSymbol(this bool v,string path) {
            string url =string.IsNullOrEmpty( path)?@"/Images":path;
            return string.Format(@"<img src=""{0}/{1}"" border=""0"" />", url, v ? @"yes.png" : @"no.png");
        }

        public static string ToUrlEncode(this string strCode)
        {
            StringBuilder sb = new StringBuilder();
            byte[] byStr = System.Text.Encoding.UTF8.GetBytes(strCode); //默认是System.Text.Encoding.Default.GetBytes(str)  
            System.Text.RegularExpressions.Regex regKey = new System.Text.RegularExpressions.Regex("^[A-Za-z0-9]+$");
            for (int i = 0; i < byStr.Length; i++)
            {
                string strBy = Convert.ToChar(byStr[i]).ToString();
                if (regKey.IsMatch(strBy))
                {
                    //是字母或者数字则不进行转换    
                    sb.Append(strBy);
                }
                else
                {
                    sb.Append(@"%" + Convert.ToString(byStr[i], 16));
                }
            }
            return (sb.ToString());
        }



        /// <summary>
        /// 上一次产生的主键值.
        /// </summary>
        /// <value>The last primary key.</value>
        public static string LastPrimaryKey { get { return __lastKey; } }

        /// <summary>
        /// 截取指定长度的字符
        /// </summary>
        /// <param name="Str"></param>
        /// <param name="MaxLength"></param>
        /// <param name="IsByte">是否已字节方式截取</param>
        /// <returns></returns>
        public static string GetLenString(this string strInput, int MaxLength, bool IsByte = false)
        {
            strInput = strInput.Trim();
            if (!IsByte) {
                return strInput.Substring(0, (strInput.Length > MaxLength ? MaxLength : strInput.Length));
            }
            strInput = strInput.Trim();
            int byteLen = Encoding.Default.GetByteCount(strInput);
            int startIndex = 0;
            if (byteLen > MaxLength)
            {
                string resultStr = String.Empty;
                for (int i = startIndex / 2; i < strInput.Length; i++)
                {
                    if (Encoding.Default.GetByteCount(resultStr) < MaxLength)
                    {
                        resultStr += strInput.Substring(i, 1);
                    }
                    else
                    {
                        break;
                    }
                }
                return resultStr;
            }
            else
            {
                return strInput;
            }
        }

        public static string MD5(this string Str, int Len)
        {
            string Result = Str.MD5();
            return Result.Substring(0, Len);
        }


        public static string MD5(this string Str) { 
            ////获取加密服务  
            //System.Security.Cryptography.MD5CryptoServiceProvider md5CSP = new System.Security.Cryptography.MD5CryptoServiceProvider();  
         
            ////获取要加密的字段，并转化为Byte[]数组  
            //byte[] testEncrypt = System.Text.Encoding.Unicode.GetBytes(Str);  
  
            ////加密Byte[]数组  
            //byte[] resultEncrypt = md5CSP.ComputeHash(testEncrypt);  
  
            ////将加密后的数组转化为字段(普通加密)  
            //string testResult = System.Text.Encoding.Unicode.GetString(resultEncrypt);  
  
            //作为密码方式加密   
            return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(Str, "MD5");  
        }

        /// <summary>
        /// 根据GUID获取唯一编码
        /// </summary>
        /// <param name="Str"></param>
        /// <param name="Key"></param>
        /// <returns></returns>
        public static string GetUniqueString(this Guid guid)
        {
            return guid.ToString().GetUniqueString();
        }

        /// <summary>
        /// 根据GUID获取唯一编码
        /// </summary>
        /// <param name="Str"></param>
        /// <param name="Key"></param>
        /// <returns></returns>
        public static string GetUniqueString(this string guid)
        {
            string readyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            string rtn = "";
            if (string.IsNullOrEmpty(guid))
                guid = Guid.NewGuid().ToString();
            if (guid.Length <= 48)
                guid += readyStr;
            //string guid = Key.ToString().Replace("-", "");
            for (int i = 0; i < guid.Length-24; i++)
            {
                int t = Convert.ToInt32(guid[i]) + Convert.ToInt32(guid[i + 8]) + Convert.ToInt32(guid[i + 16]) + Convert.ToInt32(guid[i + 24]);
                rtn += readyStr[t % 35];
            }

            return rtn.MD5(16);
        }


        /// <summary>
        /// 获取GUID唯一主键
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public static string GetGuidUniqueString(this string guid) {
            return
                Regex.IsMatch(guid, @"^[A-F0-9]{8}(-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.IgnoreCase | RegexOptions.Multiline) ? new Guid(guid).GetGuidUniqueString() : guid;
            //return KeyValue.GetGuidUniqueString();
        }

        /// <summary>
        /// 获取GUID唯一主键
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public static string GetGuidUniqueString(this Guid guid)
        {
            return GenUniqueString(guid.ToString());
        }


        /// <summary>
        /// 生成唯一的字符串
        /// </summary>
        /// <returns>唯一的字符串</returns>
        public static string GenUniqueString(this string guid)
        {
            string readyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            string rtn = "";
            //string guid = Guid.NewGuid().ToString();
            guid = guid.Replace("-", "");
            for (int i = 0; i < guid.Length - 24; i++)
            {
                int t = Convert.ToInt32(guid[i]) + Convert.ToInt32(guid[i + 8]) + Convert.ToInt32(guid[i + 16]) + Convert.ToInt32(guid[i + 24]);
                rtn += readyStr[t % 35];
            }

            return new Regex(@"(^\d)", RegexOptions.IgnoreCase).IsMatch(rtn) ? @"".GenUniqueString() : rtn;
        }


            /// <summary>
	        /// 获取枚举变量值的 Description 属性
	        /// </summary>
	        /// <param name="obj">枚举变量</param>
	        /// <returns>如果包含 Description 属性，则返回 Description 属性的值，否则返回枚举变量值的名称</returns>
	        public static string GetDescription(this object obj)
	        {
	            return GetDescription(obj, false);
	        }


        /// <summary>
	        /// 获取枚举变量值的 Description 属性
	        /// </summary>
	        /// <param name="obj">枚举变量</param>
	        /// <param name="isTop">是否改变为返回该类、枚举类型的头 Description 属性，而不是当前的属性或枚举变量值的 Description 属性</param>
	        /// <returns>如果包含 Description 属性，则返回 Description 属性的值，否则返回枚举变量值的名称</returns>
	        public static string GetDescription(this object obj, bool isTop)
	        {
	            if (obj == null)
	            {
	                return string.Empty;
	            }
	            try
	            {
	                Type _enumType = obj.GetType();
	                DescriptionAttribute dna = null;
	                if (isTop)
	                {
	                    dna = (DescriptionAttribute)Attribute.GetCustomAttribute(_enumType, typeof(DescriptionAttribute));
	                }
	                else{
	                    FieldInfo fi = _enumType.GetField(Enum.GetName(_enumType, obj));
	                    dna = (DescriptionAttribute)Attribute.GetCustomAttribute(_enumType, typeof(DescriptionAttribute));
	                }
	                if (dna != null && string.IsNullOrEmpty(dna.Description) == false)
	                    return dna.Description;
	            }
	            catch
	            {
	            }
	            return obj.ToString();
	        }
    }
}
